# -*- coding: utf-8 -*-
import scrapy

import json
import re
import logging
from pprint import pprint
from copy import copy, deepcopy
from FDC_spider.items import FdcEstateGuidItem, FdcBuildingItem, FdcRoomItem

logger = logging.getLogger(__name__)


class NanningSpider(scrapy.Spider):
    name = 'nanning'
    allowed_domains = ['nnfcxx.com']
    start_urls = [
        'https://www.nnfcxx.com/api/house/newHouseList?search=&buildtype=&areaid=&min_price=&max_price=&room=&min_houseearm=&max_houseearm=&catid=&page=1']

    def parse(self, response):
        resp_dict = json.loads(response.body.decode())
        try:
            assert resp_dict['code'] == '10000'
            pprint('>>>>>>>>>>当前是第{}页<<<<<<<<<<'.format(resp_dict['data']['page']))
        except Exception as e:
            logger.error('{}  获取楼盘列表页信息失败:{}  errormsg:{}'.format(response.request.url, resp_dict.get('msg', None), e))
        else:
            # 获取当前页楼盘列表
            itemList = resp_dict['data']['itemList']
            if len(itemList):
                for item in itemList:
                    item_eg = FdcEstateGuidItem()
                    item_eg['districtName'] = item.get('areaname', None)
                    item_eg['districtName'] = item_eg['districtName'] if item_eg['districtName'] and '区' in item_eg[
                        'districtName'] else None
                    item_eg['estateName'] = item.get('title', None)
                    item_eg['estateAddress'] = item.get('address', None)
                    item_eg['developerName'] = item.get('kfs', None)
                    item_eg['estateId'] = item.get('itemid', None)
                    item_eg['lngBd'] = item.get('lat', None)
                    item_eg['latBd'] = item.get('lng', None)
                    item_eg['coordinate'] = item.get('map', None)
                    item_eg['propertyType'] = item.get('buildtype', None)
                    # 楼盘详情url
                    eg_detail_url_temp = 'https://www.nnfcxx.com/api/house/newHouseDetail?houseId={}'
                    yield scrapy.Request(
                        eg_detail_url_temp.format(item_eg['estateId']),
                        callback=self.parse_estate,
                        meta={'item_eg': deepcopy(item_eg)},
                        priority=5,
                    )

            # 翻页
            total_page = int(resp_dict['data']['totalPage'])
            url_temp = 'https://www.nnfcxx.com/api/house/newHouseList?search=&buildtype=&areaid=&min_price=&max_price=&room=&min_houseearm=&max_houseearm=&catid=&page={}'
            url_li = [url_temp.format(i) for i in range(2, total_page)]
            for url in url_li:
                yield scrapy.Request(
                    url,
                )

    def parse_estate(self, response):
        """
        获取楼盘详情
        :param response:
        :return:
        """
        item_eg = copy(response.meta['item_eg'])
        resp_dict = json.loads(response.body.decode())
        try:
            assert resp_dict['code'] == '10000'
        except Exception as e:
            logger.error('{}  {}楼盘详情信息获取失败:{}  errormsg:{}'.format(response.request.url, item_eg['estateName'],
                                                                   resp_dict.get('msg', None), e))
            item_eg['landUsageTerm'] = None
            item_eg['estateTotalArea'] = None
            item_eg['totalRoomNo'] = None
            item_eg['parkingSpacesNum'] = None
            item_eg['floorAreaRatio'] = None
            item_eg['greeningRate'] = None
            item_eg['propertyCompany'] = None
            item_eg['propertyManagementFee'] = None
            item_eg['avgPrice'] = None
            yield item_eg
        else:
            item_eg['landUsageTerm'] = resp_dict['data']['detail'].get('lpYear', None)
            item_eg['estateTotalArea'] = resp_dict['data']['detail'].get('lpTotalarea', None)
            item_eg['totalRoomNo'] = resp_dict['data']['detail'].get('lpNumber', None)
            item_eg['parkingSpacesNum'] = resp_dict['data']['detail'].get('lpCar', None)
            item_eg['floorAreaRatio'] = resp_dict['data']['detail'].get('lpVolume', None)
            item_eg['greeningRate'] = resp_dict['data']['detail'].get('lpGreen', None)
            item_eg['propertyCompany'] = resp_dict['data']['detail'].get('lpCompany', None)
            item_eg['propertyManagementFee'] = resp_dict['data']['detail'].get('lpCosts', None)
            avg_price_dict = {'住宅': resp_dict['data']['detail'].get('zhprice', None),
                              '商业': resp_dict['data']['detail'].get('syprice', None),
                              '办公': resp_dict['data']['detail'].get('bgprice', None),
                              '车位': resp_dict['data']['detail'].get('cwprice', None),
                              '其它': resp_dict['data']['detail'].get('qtprice', None),
                              '经济适用房': resp_dict['data']['detail'].get('jjsyfprice', None),
                              '限价商品房': resp_dict['data']['detail'].get('xjspfprice', None),
                              '安置房': resp_dict['data']['detail'].get('cqazfprice', None),
                              }
            item_eg['avgPrice'] = {i: avg_price_dict[i] for i in avg_price_dict if avg_price_dict[i]}
            # 楼栋详情列表url
            bd_li_url_temp = 'https://www.nnfcxx.com/api/house/buildingTable?houseId={}'
            yield item_eg
            yield scrapy.Request(
                bd_li_url_temp.format(item_eg['estateId']),
                callback=self.parse_building_li,
                meta={'item_eg': deepcopy(item_eg)},
                priority=6,
            )

    def parse_building_li(self, response):
        """
        获取楼栋详情列表
        :param response:
        :return:
        """
        item_eg = copy(response.meta['item_eg'])
        resp_dict = json.loads(response.body.decode())
        try:
            assert resp_dict['code'] == '10000'
        except Exception as e:
            logger.error('{}  {}楼栋列表信息获取失败:{}  errormsg:{}'.format(response.request.url, item_eg['estateName'],
                                                                   resp_dict.get('msg', None), e))
        else:
            building_li = resp_dict['data'].get('buildings', [])
            if len(building_li):
                item_bd = FdcBuildingItem()
                item_bd['districtName'] = item_eg['districtName']
                item_bd['estateName'] = item_eg['estateName']
                item_bd['estateId'] = item_eg['estateId']
                item_bd['developerName'] = item_eg['developerName']
                for building_dict in building_li:
                    item_bd['blockName'] = building_dict.get('building_no', None)
                    item_bd['buildingId'] = building_dict.get('building_id', None)
                    assert item_bd['buildingId']
                    # 单元列表url
                    unit_li_url_temp = 'https://www.nnfcxx.com/api/house/buildingTable?houseId={}&buildingId={}'
                    yield item_bd
                    yield scrapy.Request(
                        unit_li_url_temp.format(item_bd['estateId'], item_bd['buildingId']),
                        callback=self.parse_unit_li,
                        meta={'item_bd': deepcopy(item_bd)},
                        priority=7,
                    )
            else:
                logger.warning('{}  {}楼栋列表信息获取为空'.format(response.request.url, item_eg['estateName']))

    def parse_unit_li(self, response):
        """
        获取单元列表信息
        :param response:
        :return:
        """
        item_bd = copy(response.meta['item_bd'])
        resp_dict = json.loads(response.body.decode())
        try:
            assert resp_dict['code'] == '10000'
        except Exception as e:
            logger.error('{}  {}-{}单元列表信息获取失败:{}  errormsg:{}'.format(response.request.url, item_bd['estateName'],
                                                                      item_bd['blockName'],
                                                                      resp_dict.get('msg', None), e))
        else:
            unit_li = resp_dict['data'].get('units', [])
            if len(unit_li):
                item_rm = FdcRoomItem()
                item_rm['districtName'] = item_bd['districtName']
                item_rm['estateName'] = item_bd['estateName']
                item_rm['estateId'] = item_bd['estateId']
                item_rm['blockName'] = item_bd['blockName']
                item_rm['buildingId'] = item_bd['buildingId']
                for unit_dict in unit_li:
                    item_rm['unitName'] = unit_dict.get('unit', None)
                    item_rm['unitNo'] = unit_dict.get('IUNIT', None)
                    assert item_rm['unitName']
                    # 楼层列表url
                    floor_li_url_temp = 'https://www.nnfcxx.com/api/house/buildingTable?houseId={}&buildingId={}&unitNo={}'
                    yield scrapy.Request(
                        floor_li_url_temp.format(item_rm['estateId'], item_rm['buildingId'], item_rm['unitNo']),
                        callback=self.parse_floor_li,
                        meta={'item_rm': deepcopy(item_rm)},
                        priority=8,
                    )
            else:
                logger.warning('{}  {}-{}单元列表信息获取为空'.format(response.request.url, item_bd['estateName'],
                                                            item_bd['blockName']))

    def parse_floor_li(self, response):
        """
        获取楼层列表信息
        :param response:
        :return:
        """
        item_rm = copy(response.meta['item_rm'])
        resp_dict = json.loads(response.body.decode())
        try:
            assert resp_dict['code'] == '10000'
        except Exception as e:
            logger.error('{}  {}-{}-{}楼层列表信息获取失败:{}  errormsg:{}'.format(response.request.url, item_rm['estateName'],
                                                                         item_rm['blockName'], item_rm['unitName'],
                                                                         resp_dict.get('msg', None), e))
        else:
            floor_li = resp_dict['data'].get('floors', [])
            if len(floor_li):
                for floor_dict in floor_li:
                    item_rm['roomFloor'] = floor_dict.get('floor_name', None)
                    assert item_rm['roomFloor']
                    # 房号列表url
                    room_li_url_temp = 'https://www.nnfcxx.com/api/house/buildingTable?houseId={}&buildingId={}&unitNo={}&floorNo={}'
                    yield scrapy.Request(
                        room_li_url_temp.format(item_rm['estateId'], item_rm['buildingId'], item_rm['unitNo'],
                                                floor_dict['IFLOOR']),
                        callback=self.parse_room_li,
                        meta={'item_rm': deepcopy(item_rm)},
                        priority=9,
                    )
            else:
                logger.warning('{}  {}-{}-{}楼层列表信息获取为空'.format(response.request.url, item_rm['estateName'],
                                                               item_rm['blockName'], item_rm['unitName']))

    def parse_room_li(self, response):
        """
        获取房号列表信息
        :param response:
        :return:
        """
        item_rm = copy(response.meta['item_rm'])
        resp_dict = json.loads(response.body.decode())
        try:
            assert resp_dict['code'] == '10000'
        except Exception as e:
            logger.error('{}  {}-{}-{}-{}房号列表信息获取失败:{}  errormsg:{}'.format(response.request.url, item_rm['estateName'],
                                                                            item_rm['blockName'], item_rm['unitName'],
                                                                            item_rm['roomFloor'],
                                                                            resp_dict.get('msg', None), e))
        else:
            room_li = resp_dict['data'].get('houses', [])
            if len(room_li):
                for room_dict in room_li:
                    item_rm['roomNo'] = room_dict.get('room_no', None)
                    item_rm['roomArea'] = room_dict.get('building_area', None)
                    item_rm['roomUse'] = room_dict.get('use_type', None)
                    item_rm['unitPrice'] = room_dict.get('proposed_unit_price', None)
                    saleable, is_signing, is_filing, is_limit, is_mortgage_under_construction, is_sign = (
                        int(i) if i and re.findall(r'\d+', str(i)) else i for i in [room_dict.get(j, None) for j in
                                                                                    ['saleable', 'is_signing',
                                                                                     'is_filing', 'is_limit',
                                                                                     'is_mortgage_under_construction',
                                                                                     'is_sign']])
                    saleStatus = -1 == saleable and (
                        1 if 1 == is_signing or -1 == is_filing or 'A' == is_sign else -1 != is_mortgage_under_construction and -1 != is_limit or 2)
                    if saleStatus is 1:
                        item_rm['saleStatus'] = '已售'
                    elif saleStatus is 2:
                        item_rm['saleStatus'] = '不可售'
                    elif saleStatus is True:
                        item_rm['saleStatus'] = '未售'
                    else:
                        item_rm['saleStatus'] = '棚改、新市民'
                    yield deepcopy(item_rm)
            else:
                logger.warning('{}  {}-{}-{}-{}房号列表信息获取为空'.format(response.request.url, item_rm['estateName'],
                                                                  item_rm['blockName'], item_rm['unitName'],
                                                                  item_rm['roomFloor']))
